package scenetracer.core.shader;

import java.util.List;

import scenetracer.SceneState;
import scenetracer.SceneTracer;
import scenetracer.core.Primitive;
import scenetracer.core.Ray;
import scenetracer.core.Scene;
import scenetracer.core.Texture;
import scenetracer.core.light.Light;
import scenetracer.image.Color;
import scenetracer.math.Point3;
import scenetracer.math.Vector3;

public class PhongShader extends Shader{

	private float exp;
	private int samples;
	private boolean differ;
	
	protected Color sColor;
	protected Color aColor;
	protected final float AREFLECTIONRATE = 0.1f;

	public PhongShader(String name, int penumbra) {
		super(name, penumbra);
		this.type = "phong";
	}
	
	@Override
	public void setPrim(Primitive primitive) {
		primitive.setReflectionK(0.09f);		
	}
	
	private void setReflectionS(Color reflectionColor) {
		/*
		if( prim instanceof Triangle && samples > 0 ) 
			reflectionColor.add(sColor);
		else
			reflectionColor.add(Color.Black);
			
		 */
		if(differ)
			reflectionColor.mul(sColor);
		else
			reflectionColor.set(Color.BLACK);
		
	}
	
	

	public void setSColor(Color sColor) {
		this.sColor = sColor;		
	}

	public void setExp(float exp) {
		this.exp = exp;		
	}

	public void setSamples(int samples) {
		this.samples = samples;
		this.differ = samples > 0;
			
	}
	
	private boolean getObsRays(SceneState state, Light light, Point3 interP){
		SceneTracer tracer = state.getTracer();
		return !tracer.lightObs(state.getScene(), new Ray(interP, 
				light.getDirLights(state.getIntersection()).get(0)), light, state.getPrimitive());
	}
	
	@Override
	public void shade(SceneState state) {
		
		float scalarP = 0;
		
		Color atteLightC = new Color(Color.BLACK);
		Color diffColor = new Color(Color.BLACK);
		Color specColor = new Color(Color.BLACK);
		Scene scene = state.getScene();
		Point3 interP = state.getIntersection().getIntersectionPoint();
		
		for (Light light : scene.getLights())
		{

			List<Vector3> dirs = light.getDirLights(state.getIntersection());
			if(getObsRays(state, light, interP))
			{
				scalarP = Vector3.dot(dirs.get(0), state.getNormal());
				
				if(scalarP > 0)
				{
					Color.mul(light.getAtte(interP)*CORRECTION, light.getColor(), atteLightC);
					Color.mul(getPointColor(state.getPrimitive(), interP), atteLightC, diffColor);
					state.getColor().madd(Math.abs(scalarP), diffColor);
				}
				
				
				scalarP = Vector3.dot(state.getRay().getDirection(), Vector3.sub(dirs.get(0), 
						new Vector3(state.getNormal()).mul(2 * Vector3.dot(dirs.get(0), state.getNormal())), 
						new Vector3()));

				if (scalarP > 0){		
					specColor.madd((float)Math.pow(scalarP, exp), light.getColor());
					specColor.mul(sColor);
					state.getColor().add(specColor);
				}
				
				setReflectionS(state.getReflectionColor());

				

			}
		}
		//state.getColor().add(aColor.mul())
		
	}

	public void setTex(String Path) {
			tex = new Texture(Path);
	}
	

}
